package matrix

import (
	"errors"
	"strconv"
	"strings"
)

const testVersion = 1

type Matrix struct {
	numbers [][]int
}

func New(input string) (m *Matrix, err error) {

	s := strings.Split(input, "\n")
	m = &Matrix{}
	m.numbers = make([][]int, len(s))

	colCount := -1
	for i := 0; i < len(s); i++ {
		ss := strings.Split(strings.Trim(s[i], " "), " ")

		if len(ss) == 0 {
			err = errors.New("error: empty row")
			return
		}

		if colCount == -1 {
			colCount = len(ss)
		} else {
			if colCount != len(ss) {
				err = errors.New("error: uneven rows")
				return
			}

		}

		m.numbers[i] = make([]int, len(ss))
		for j := 0; j < len(ss); j++ {
			if ss[j] == "" {
				m.numbers[i][j] = 0
				continue
			}

			// if _, ok := strconv.ParseInt(ss[j], 0, 32); ok != nil {
			// 	err = errors.New("error: overflows int64")
			// 	return
			// }

			if r, ok := strconv.Atoi(ss[j]); ok == nil {
				m.numbers[i][j] = r
			} else {
				err = errors.New("error: overflows int64")
				return
			}
		}
	}

	return
}

func (m Matrix) Set(r int, c int, val int) (ok bool) {
	if r < 0 || c < 0 {
		return
	}

	if r >= len(m.numbers) {
		return
	}

	if c >= len(m.numbers[0]) {
		return
	}

	m.numbers[r][c] = val
	ok = true
	return
}

func (m Matrix) Rows() (r [][]int) {
	rLength := len(m.numbers)

	r = make([][]int, rLength)
	for i := 0; i < rLength; i++ {
		cLength := len(m.numbers[i])
		r[i] = make([]int, cLength)
		for j := 0; j < cLength; j++ {
			r[i][j] = m.numbers[i][j]
		}
	}

	return
}

func (m Matrix) Cols() (r [][]int) {
	rLength := len(m.numbers)
	cLength := len(m.numbers[0])
	r = make([][]int, cLength)

	for i := 0; i < cLength; i++ {
		r[i] = make([]int, rLength)
	}

	for i := 0; i < rLength; i++ {
		for j := 0; j < cLength; j++ {
			r[j][i] = m.numbers[i][j]
		}
	}

	return
}
